package com.platform.common.core.oss;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.google.gson.Gson;

import com.platform.common.core.oss.baen.ALiOSSStorage;
import com.platform.common.core.oss.baen.OssType;
import com.platform.common.core.oss.baen.Qiniu;
import com.platform.common.core.oss.baen.TengXun;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Objects;

/**
 * @author guoyunfei on 2021/7/7 22:51
 * @className AttachFileService
 * @description TODO
 * @Version 1.0
 */

@Service
public class AttachFileService {

    @Resource
    private Qiniu qiniu;

    @Resource
    private ALiOSSStorage aliyun;

    @Resource
    private TengXun tengXun;

    @Resource
    private OssType ossType;

    public final static String NORM_MONTH_PATTERN = "yyyy/MM/dd/";

    /**
     * 获取存储类型
     * @return
     */
    public String getOssType(){
        return ossType.getStorageType();
    }


    public Configuration qiniuZone(String zoneStr) {
        Zone zone = null;
        if (Objects.equals(zoneStr, QiniuZone.HUA_BEI)) {
            zone = Zone.huabei();
        } else if (Objects.equals(zoneStr, QiniuZone.HUA_DONG)) {
            zone = Zone.huadong();
        } else if (Objects.equals(zoneStr, QiniuZone.HUA_NAN)) {
            zone = Zone.huanan();
        } else if (Objects.equals(zoneStr, QiniuZone.BEI_MEI)) {
            zone = Zone.beimei();
        } else if (Objects.equals(zoneStr, QiniuZone.XIN_JIA_PO)) {
            zone = Zone.xinjiapo();
        }
        return new Configuration(zone);
    }

    public Zone getQiniuZone(String zoneStr) {
        Configuration configuration = qiniuZone(zoneStr);
        return configuration.zone;
    }


    /**
     * 获取域名
     */
    public String getDomain() throws IOException {

        if(ossType.getStorageType().equals("0")){
            return qiniu.getResourcesUrl();
        }else if(ossType.getStorageType().equals("1")){
            return aliyun.getResourcesUrl();
        }
        return tengXun.getResourcesUrl();
    }

    /**
     * 文件上传统一入口
     */
    public String uploadFile(MultipartFile file,String suffix) throws IOException {

        if(ossType.getStorageType().equals("0")){
            return uploadFileQiniu(file);
        }else if(ossType.getStorageType().equals("1")){
            return uploadFileAliyun(file,suffix);
        }
        return uploadTengxun(file);
    }

    /**
     * 文件删除统一入口
     */
    public Object deleteFile(String fileName) throws IOException {

        if(ossType.getStorageType().equals("0")){
            return deleteQiniu(fileName);
        }else if(ossType.getStorageType().equals("1")){
            deleteAliyun(fileName);
        }
        return deleteTengxun(tengXun.getBucket(),fileName);
    }

    /**
     * 上传文件(七牛云)
     * @param file
     * @return
     * @throws QiniuException
     */
    public String uploadFileQiniu(MultipartFile file) throws IOException {
        String filename = file.getOriginalFilename();
        String extName = FileUtil.extName(filename);
        //String rFileName = DateUtil.format(new Date(), NORM_MONTH_PATTERN) + IdUtil.simpleUUID() + "." + extName;
        String rFileName =  IdUtil.simpleUUID() + "." + extName;
        //存储东南亚
        Configuration cfg = new Configuration(getQiniuZone(qiniu.getQzone()));
        UploadManager uploadManager = new UploadManager(cfg);
        Auth auth = Auth.create(qiniu.getAccessKey(), qiniu.getSecretKey());
        String upToken = auth.uploadToken(qiniu.getBucket(), rFileName);
        Response response = uploadManager.put(file.getBytes(), rFileName, upToken);

        DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        System.out.println(putRet);
        return rFileName;
    }

    /**
     * 上传文件(阿里云)
     * @param file
     * @return
     * @throws QiniuException
     */
    public String uploadFileAliyun(MultipartFile file,String suffix) throws IOException {
        String filename = file.getOriginalFilename();
        String extName = FileUtil.extName(filename);
        //String rFileName = DateUtil.format(new Date(), NORM_MONTH_PATTERN) + IdUtil.simpleUUID() + "." + extName;
        if(StringUtils.isNotBlank(suffix)){
            extName = suffix;
        }
        String rFileName = IdUtil.simpleUUID() + "." + extName;

        OSS oss = new OSSClientBuilder().build(aliyun.getEndpoint(), aliyun.getAccessKeyId(), aliyun.getAccessKeySecret());
        //流式上传-文件流
        PutObjectRequest putObjectRequest = new PutObjectRequest(aliyun.getBucket(), rFileName, new ByteArrayInputStream(file.getBytes()));
        oss.putObject(putObjectRequest);
        oss.shutdown();
        return rFileName;
    }

    public boolean deleteAliyun (String fileName){
        OSS ossClient = new OSSClientBuilder().build(aliyun.getEndpoint(), aliyun.getAccessKeyId(), aliyun.getAccessKeySecret());
        // 删除文件或目录。如果要删除目录，目录必须为空。
        ossClient.deleteObject(aliyun.getBucket(), fileName);
        // 关闭OSSClient。
        ossClient.shutdown();
        return true;
    }

    public int deleteQiniu (String fileName){
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zoneAs0());
        Auth auth = Auth.create(qiniu.getAccessKey(), qiniu.getSecretKey());
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            Response delete = bucketManager.delete(qiniu.getBucket(), fileName);
            return delete.statusCode;
        } catch (QiniuException ex) {
            //如果遇到异常，说明删除失败
            ex.printStackTrace();
            System.err.println(ex.code());
            System.err.println(ex.response.toString());
        }
        return -1;
    }


    /**
     * * 初始化CosClient相关配置， appid、accessKey、secretKey、region * @return
     */
    public COSClient getCosClient() {
        COSCredentials cred = new BasicCOSCredentials(tengXun.getAccessKeyId(), tengXun.getAccessKeySecret()); // 不传APPID也可以，APPID和ACCESSKE已经关联过
        ClientConfig clientConfig = new ClientConfig(new Region(tengXun.getCosRegion()));
        COSClient cosclient = new COSClient(cred, clientConfig);
        return cosclient;
    }


    /**
     * 腾讯云文件上传
     */
    public String uploadTengxun(MultipartFile file) throws IOException {

        String filename = file.getOriginalFilename();
        String extName = FileUtil.extName(filename);
        String key = IdUtil.simpleUUID() + "." + extName;

        ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setContentType("image/jpeg");

        metadata.setContentLength(file.getBytes().length);
        com.qcloud.cos.model.PutObjectRequest putObjectRequest = new com.qcloud.cos.model.PutObjectRequest(
                tengXun.getBucket(), key, new ByteArrayInputStream(file.getBytes()),metadata);

        // 设置存储类型, 默认是标准(Standard), 低频(standard_ia)
        //putObjectRequest.setStorageClass(StorageClass.Standard_IA);
        COSClient cc = getCosClient();
        try {
            PutObjectResult putObjectResult = cc.putObject(putObjectRequest);
            System.out.println(putObjectResult);
            return key;
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        }
        // 关闭客户端
        cc.shutdown();
        return null;
    }

    /**
     * 腾讯云删除
     */
    public Object deleteTengxun(String bucket ,String key)  {
        COSClient cosClient = getCosClient();
        cosClient.deleteObject(bucket,key);
        cosClient.shutdown();
        return true;
    }

}
